﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.ComponentModel;

namespace Seven.Tools.Extension
{
    /// <summary>
    /// 提供一组对 类型 <see cref="System.Type"/> 操作方法的扩展。
    /// </summary>
    public static class TypeExtensions
    {
        /// <summary>
        /// 判断指定类型是否为数值类型
        /// </summary>
        /// <param name="_this">要检查的类型</param>
        /// <returns>是否是数值类型</returns>
        public static bool IsNumeric(this Type _this)
        {
            return _this == typeof(Byte)
                || _this == typeof(Int16)
                || _this == typeof(Int32)
                || _this == typeof(Int64)
                || _this == typeof(SByte)
                || _this == typeof(UInt16)
                || _this == typeof(UInt32)
                || _this == typeof(UInt64)
                || _this == typeof(Decimal)
                || _this == typeof(Double)
                || _this == typeof(Single);
        }

        /// <summary>
        /// 判断当前 <see cref="System.Type"/> 指示的类型是否继承于（或等价于）某个 <see cref="System.Type"/> 类型。
        /// </summary>
        /// <param name="_this">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="c">用于比较的 <see cref="System.Type"/> 类型对象。</param>
        /// <returns>如果当前类型等价或继承与指定的类型，则返回 true，否则返回 false。</returns>
        public static bool IsInhertOf(this System.Type _this, System.Type c)
        {
            return _this == c || _this.IsSubclassOf(c);
        }

        /// <summary>
        /// 判断当前 <see cref="System.Type"/> 指示的类型是否实现或(等价于)某个 <see cref="System.Type"/> 指示的接口。
        /// </summary>
        /// <param name="_this">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="c">用于比较的 <see cref="System.Type"/> 类型对象，表示一个接口类型。</param>
        /// <returns>如果当前类型等价或继承与指定的接口类型，则返回 true，否则返回 false。</returns>
        public static bool IsImplementOf(this System.Type _this, System.Type c)
        {
            return _this == c || _this.GetInterfaces().Contains(c);
        }

        /// <summary>
        /// 判断当前 <see cref="System.Type"/> 指示的类型是否实现、继承等价于某个 <see cref="System.Type"/> 指示的类型或接口。
        /// </summary>
        /// <param name="_this">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="c">用于比较的 <see cref="System.Type"/> 类型对象。</param>
        /// <returns>如果当前类型实现、继承等价于指定的类型或接口，则返回 true，否则返回 false。</returns>
        public static bool IsInhertOrImplementOf(this System.Type _this, System.Type c)
        {
            return _this.IsInhertOf(c) || _this.IsImplementOf(c);
        }

        /// <summary>
        /// 获取可空类型的基本类型，若当前Type不是“可空类型”，则返回当前Type
        /// </summary>
        /// <param name="_this">当前 <see cref="System.Type"/> 对象。</param>
        /// <returns></returns>
        public static Type GetUnNullableType(this System.Type _this)
        {
            if (_this.IsGenericType && _this.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                //如果是泛型方法，且泛型类型为Nullable<>则视为可空类型
                return Nullable.GetUnderlyingType(_this);
            }
            return _this;
        }
    }
}
